// 
//  Copyright 2011  reda
// 
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
// 
//        http://www.apache.org/licenses/LICENSE-2.0
// 
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
using System;
using System.Collections.Generic;
using NHibernate.Validator.Constraints;
using System.Linq;

namespace ManiacMusicManager.Data.Core
{
	/// <summary>
	/// Représente un artiste musicien (qui peut être une personne ou un groupe de personnes)
	/// </summary>
	public class Artiste : Entity
	{
		#region Types Definition
		/// <summary>
		/// Type d'un artiste
		/// </summary>
		public enum ArtisteType
		{
			/// <summary>
			/// Si le type de l'artiste est non connu ou non encore renseigné
			/// </summary>
			Inconnu,
			/// <summary>
			/// Si c'est un artiste solo (individu, ça n'exclu pas qu'il peut appartenir en même temps à des groupes)
			/// </summary>
			Personne,
			/// <summary>
			/// Si c'est un ensemble d'artistes évoluant en groupe
			/// </summary>
			Groupe,
			/// <summary>
			/// Si c'est une chorale
			/// </summary>
			Chorale,
			/// <summary>
			/// Si c'est un orchestre
			/// </summary>
			Orchestre,
			/// <summary>
			/// Si le type est connu mais n'est pas disponible dans la liste des types
			/// </summary>
			Autre
		}
		#endregion
		
		public Artiste ()
			: base()
		{
			this.Albums			= new List<Album>();
			this.Chansons		= new List<Chanson>();
			this.Aliases		= new List<string>();
			this.Membres		= new List<Artiste>();
			this.RelatedArtists	= new List<Artiste>();
			this.ArtisteTags	= new List<string>();
		}
		
		#region Properties
		
		/// <summary>
		/// Nom qui sera utilisé pour trier une liste d'artistes par ordre alphabétique
		/// </summary>
		[NotNullNotEmpty]
		public virtual string SortName {
			get;
			set;
		}
		
		/// <summary>
		/// Autres noms de l'artiste
		/// </summary>
		public virtual IList<string> Aliases {
			get;
			set;
		}
		
		/// <summary>
		/// Nationalité de l'artiste
		/// </summary>
		[NotNullNotEmpty]
		public virtual string Nationalite {
			get;
			set;
		}
		
		/// <summary>
		/// Année depuis laquel a débuté la carriere
		/// </summary>
		[NotNull]
		public virtual uint? AnneeDebutCarriere {
			get;
			set;
		}
		
		/// <summary>
		/// Date de naissance de l'artiste
		/// </summary>
		[NotNull]
		public virtual DateTime? DateNaissance {
			get;
			set;
		}
		
		/// <summary>
		/// Date de deces de l'artiste (si il est mort)
		/// </summary>
		[NotNull]
		public virtual DateTime? DateDeces {
			get;
			set;
		}
		
		/// <summary>
		/// Liste des albums dans lesquels a participé l'artiste
		/// </summary>
		[NotNullNotEmpty]
		public virtual IEnumerable<Album> Albums {
			get;
			private set;
		}
		
		/// <summary>
		/// Liste des chansons dans lesquelles à participé l'artiste
		/// </summary>
		[NotNullNotEmpty]
		public virtual IEnumerable<Chanson> Chansons {
			get;
			private set;
		}
		
		/// <summary>
		/// Type de l'artiste
		/// </summary>
		public virtual ArtisteType TypeArtiste {
			get;
			set;
		}
		
		/// <summary>
		/// lien wikipedia de l'article traitant de l'artiste
		/// </summary>
		[NotNullNotEmpty]
		public virtual string WikipediaURL {
			get;
			set;
		}
		
		/// <summary>
		/// site officiel de l'artiste
		/// </summary>
		[NotNullNotEmpty]
		public virtual string OfficialWebsite {
			get;
			set;
		}
		
		/// <summary>
		/// Liste des membres d'un groupe
		/// </summary>
		public virtual IList<Artiste> Membres {
			get;
			set;
		}
		
		/// <summary>
		/// Liste des artistes en liens avec l'artiste courant
		/// </summary>
		public virtual IList<Artiste> RelatedArtists {
			get;
			set;
		}
		
		/// <summary>
		/// Liste de mots clefs liés à l'artiste
		/// </summary>
		public virtual IList<string> ArtisteTags {
			get;
			set;
		}
		
		/// <summary>
		/// Identifiant MusicBrainz de l'artiste courant
		/// </summary>
		[NotNullNotEmpty]
		public virtual string MusicBrainzId {
			get;
			set;
		}
		#endregion
		

	#region Link/Unlink Album
		/// <summary>
		/// Lier avec un <see cref="Album"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void LinkAlbum(Album obj) {
			if(! this.Albums.Contains(obj))
				(this.Albums as IList<Album>).Add(obj);
			
			if(! obj.Artistes.Contains(this))
				(obj.Artistes as IList<Artiste>).Add(this);
		}
		
		/// <summary>
		/// Delier un <see cref="Album"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void UnlinkAlbum(Album obj) {
			if(this.Albums.Contains(obj))
				(this.Albums as IList<Album>).Remove(obj);
			
			if(obj.Artistes.Contains(this))
				(obj.Artistes as IList<Artiste>).Remove(this);
		}
	#endregion

	#region Link/Unlink Chanson
		/// <summary>
		/// Lier avec un <see cref="Chanson"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void LinkChanson(Chanson obj) {
			if(! this.Chansons.Contains(obj))
				(this.Chansons as IList<Chanson>).Add(obj);
			
			if(! obj.Artistes.Contains(this))
				(obj.Artistes as IList<Artiste>).Add(this);
		}
		
		/// <summary>
		/// Delier un <see cref="Chanson"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void UnlinkChanson(Chanson obj) {
			if(this.Chansons.Contains(obj))
				(this.Chansons as IList<Chanson>).Remove(obj);
			
			if(obj.Artistes.Contains(this))
				(obj.Artistes as IList<Artiste>).Remove(this);
		}
	#endregion

	}
}

